#ifndef REMINDER_H
#define REMINDER_H

#include <QObject>
#include <QTimer>
#include <QDateTime>
#include <QUuid>

class ReminderItem;
//class Logger;

class Reminder : public QObject
{
    Q_OBJECT

public:
    Reminder(QObject *parent = 0);
    Reminder(QObject *parent, const QString& name);
    Reminder(QObject *parent, int index, const QString& name);
    Reminder(const Reminder& other);
    ~Reminder();

    enum ReminderType {
        Once,
        Minutely,
        Hourly,
        Daily,
        Monthly,
        MonthlyByDay,
        Yearly,
        YearlyByDay,
        Timeout
    };

    enum ReminderState {
        Runned,
        Postponed,
        Stopped
    };

    enum ShutdownType {
        LogOff,
        TurnOff,
        Restart,
        Hibernate
    };

signals:
    void remind(Reminder* reminder);
    void changeState(Reminder* reminder);
    void stopNotify();

protected:
    void run();

public slots:
    inline void setTooltip(const bool tip){ _tip = tip; }
    inline void setDialog(const bool dialog){ _dialog = dialog; }
    inline void setAudio(const bool audio){ _audio = audio; }
    inline bool hasTooltip() const { return _tip; }
    inline bool hasDialog() const { return _dialog; }
    inline bool hasAudio() const { return _audio; }
    inline bool hasAutoclose() const { return _autoclose; }
    inline void setTooltipMsg(const QString& message = QString::null){
        tooltip = message;
        this->setTooltip(true);
    }
    inline void setDialogMsg(const QString& message = QString::null){
        dialog = message;
        this->setDialog(true);
    }
    inline void setAudioName(const QString& name = QString::null){
        audio = name;
        this->setAudio(true);
    }
    inline void setAutocloseInterval(const int secs) {
        autoclose = secs;
        this->setAutoclose(true);
    }
    inline void setAutoclose(const bool close){
        _autoclose = close;
        if(!getAutocloseInterval()) autoclose = 10;
    }
    inline void setName(const QString& _name){ name = _name; }
    inline void setMinutes(const int _minutes){ minutes = _minutes; }
    inline void setHours(const int _hours){ hours = _hours; }
    inline void setStart(const QDateTime datetime){ _start = datetime; nextRun = datetime; }
    inline void setNextRun(const QDateTime datetime){ nextRun = datetime; }
    inline int getAutocloseInterval() const { return autoclose; }
    inline QString getTooltipMsg() const { return tooltip; }
    inline QString getDialogMsg() const { return dialog; }
    inline QString getAudioName() const { return audio; }
    inline QString getName() const { return name; }
    inline int getMinutes() const { return minutes; }
    inline int getHours() const { return hours; }
    inline QDateTime getStart() const { return _start; }
    inline QDateTime getNextRun() const { return nextRun; }
    inline Reminder::ReminderState getState() const { return state; }
    inline void increaseNextRun(const int secs) { nextRun = nextRun.addSecs(secs); }
    inline void setType(ReminderType t){ type = t; }
    inline Reminder::ReminderType getType() const { return type; }
    inline ReminderItem* getItem() { return item; } 
    inline bool* getDays() { return days; }
    inline void setIndex(const int index = 0) { idx = index; }
    inline int getIndex() const { return idx; }
    inline void setTimeout(const int secs) { timeout = secs; }
    inline int getTimeout() const { return timeout; }
    inline void setUrl(const QString& uri) { url = uri; }
    inline QString getUrl() const { return url; }
    inline bool hasUrl() const { return _url; }
    inline void setLoadUrl(const bool set) { _url = set; }
    inline void setAutodelete(const bool autodelete) { _autodelete = autodelete; }
    inline bool getAutodelete() const { return _autodelete; }
    inline void setShutdown(const bool shutdown) { _shutdown = shutdown; }
    inline bool getShutdown() const { return _shutdown; }
    inline void setShutdownType(const Reminder::ShutdownType type) { sh_type = type; }
    inline Reminder::ShutdownType getShutdownType() const { return sh_type; }
    inline void setShutdownTimeout(const int secs) { sh_timeout = secs; }
    inline int getShutdownTimeout() const { return sh_timeout; }
    inline void setExecute(const bool set) { _execute = set; }
    inline bool getExecute() const { return _execute; }
    inline void setExecutePath(const QString &path) { execute = path; }
    inline QString getExecutePath() const { return execute; }
    inline void setExecuteArgs(const QString& args) { execute_args = args; }
    inline QString getExecuteArgs() const { return execute_args; }
    inline void setCheckMissed(const bool check) {_check_missed = check; }
    inline bool hasCheckMissed() const { return _check_missed; }
    QString getStrState() const;

    inline QUuid getId() const { return id; }

    inline void setLastCall(const QDateTime datetime) { lastCall = datetime; }
    inline QDateTime getLastCall() const { return lastCall; }

    void setDays(const bool* _days);
    void setItem(ReminderItem* i);
    void setIcon();

    void setState(Reminder::ReminderState s);

    void start();
    void stop();
    void suspend();
    void stopSound();
    void postpone(uint secs);


    bool isRunned() const;

    QString missedReminders(const QDateTime& last_call) const;


    //QString getType() const;

private slots:
    void notify();

private:
    bool calculateScheduleTime();
    int weekOfMonth(const QDateTime& dt) const;
    QDateTime dayOfNextMonths(QDateTime previous, int months = 1) const;
    QDateTime dayOfPreviousMonths(QDateTime current, int months = 1) const;

    QTimer* timer;
    ReminderItem* item;

    ReminderType type;
    ReminderState state;
    ShutdownType sh_type;

    //Logger* logger;

    QString name;
    QString tooltip;
    QString dialog;
    QString audio;
    QString url;
    QString execute;
    QString execute_args;

    int minutes;
    int hours;
    int autoclose;
    int idx;
    int timeout; //in seconds
    int sh_timeout;
    bool days[7];
    bool _audio;
    bool _dialog;
    bool _tip;
    bool _autoclose;
    bool _url;
    bool _autodelete;
    bool _shutdown;
    bool _execute;
    bool _check_missed;

    QDateTime _start;
    QDateTime nextRun;
    QDateTime lastCall;

    QUuid id;
};

#endif // REMINDER_H
